﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.ComponentModel;

namespace Jbe.TestSuite.TestDevices.SignalVisualizer.Presentation
{
    public partial class SignalControl : UserControl
    {
        public static readonly DependencyProperty ScaleXProperty = DependencyProperty.Register("ScaleX", typeof(double), 
            typeof(SignalControl), new FrameworkPropertyMetadata(1d, new PropertyChangedCallback(ScaleChangedHandler)));
        public static readonly DependencyProperty ScaleYProperty = DependencyProperty.Register("ScaleY", typeof(double),
            typeof(SignalControl), new FrameworkPropertyMetadata(1d, new PropertyChangedCallback(ScaleChangedHandler)));


        private Dictionary<object, Polyline> polylines;


        public SignalControl()
        {
            InitializeComponent();

            polylines = new Dictionary<object, Polyline>();
            
            ClipToBounds = true;
            SizeChanged += new SizeChangedEventHandler(ThisSizeChanged);
            
            DrawAxes();
        }


        /// <summary>
        /// The scaling of the x-axis.
        /// </summary>
        public double ScaleX
        {
            get { return (double)GetValue(ScaleXProperty); }
            set { SetValue(ScaleXProperty, value); }
        }

        /// <summary>
        /// The scaling of the y-axis.
        /// </summary>
        public double ScaleY
        {
            get { return (double)GetValue(ScaleYProperty); }
            set { SetValue(ScaleYProperty, value); }
        }


        public void AddSample(object device, double x, double y)
        {
            Polyline polyline;
            if (polylines.ContainsKey(device)) { polyline = polylines[device]; }
            else { polyline = AddPolyline(device); }
            
            polyline.Points.Add(new Point(x, y));
        }

        protected Polyline AddPolyline(object device)
        {
            Polyline polyline = new Polyline();
            polyline.Stroke = Brushes.Black;
            polyline.StrokeThickness = 1;

            polylines.Add(device, polyline);
            contentCanvas.Children.Add(polyline);
            return polyline;
        }

        private static void ScaleChangedHandler(DependencyObject source, DependencyPropertyChangedEventArgs e)
        {
            SignalControl control = (SignalControl)source;
            control.UpdateTransform();
        }

        private void ThisSizeChanged(object sender, SizeChangedEventArgs e)
        {
            UpdateTransform();
        }

        private void DrawAxes()
        {
            Line horizontalLine = new Line();
            horizontalLine.X1 = -3000;
            horizontalLine.Y1 = 0;
            horizontalLine.X2 = 3000;
            horizontalLine.Y2 = 0;
            horizontalLine.Stroke = System.Windows.Media.Brushes.Black;
            horizontalLine.StrokeThickness = 0.5;
            horizontalLine.IsHitTestVisible = false;

            mainCanvas.Children.Add(horizontalLine);
        }

        private void UpdateTransform()
        {
            mainCanvas.RenderTransform = new MatrixTransform(1, 0, 0, -1, 0, ActualHeight / 2);
            contentCanvas.RenderTransform = new ScaleTransform(ScaleX, ScaleY);
        }
    }
}
